<template>
  <div class="map-cont">
    <div style="width: 250px; background: #fff">
      <BasicTree
        search
        show-icon
        :treeData="treeData"
        :check-strictly="false"
        @select="handleTreeSelect"
        :selectedKeys="selectKeys"
        :fieldNames="{ key: 'id', title: 'name' }"
        treeWrapperClassName="h--[calc(100vh-157px)] overflow-auto"
        ref="asyncExpandTreeRef"
      />
    </div>
    <div style="margin-left: 16px; width: 100%" v-loading="loading">
      <template v-if="list.length">
        <div ref="searchRef">
          <Personal @change="changePersonal" :list="list" ref="personalRef" />
          <BasicForm @register="register" style="background: #fff; padding: 16px 0" />
        </div>
        <Map
          :height="MapHeight"
          :points="userPoints"
          :lat="lnglat.lat"
          :lng="lnglat.lng"
          ref="MapRef"
          mode="tiled"
        />
      </template>
      <div v-else class="no-data">
        <div class="empty-img"><img :src="emptyImg" /></div>
        <div>暂无数据</div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
  import { ref, onMounted, nextTick } from 'vue';
  import { BasicTree } from '/@/components/Tree';
  import { BasicForm, useForm } from '/@/components/Form';
  import Personal from './components/personal.vue';
  import emptyImg from '/@/assets/images/table-empty.png';
  import { Map } from '/@/components/Map';
  import { searchInfo } from './search-form.data';
  //import { getDeptUserList } from '/@/api/admin/user';
  import { getUserAddressList } from '/@/api/zkrq/projectManagement';
  import { useUserStore } from '/@/store/modules/user';
  import { CommonAddressList } from '/@/api/admin/user';
  import { getDictTypeListApi } from '/@/api/admin/dict';
  import { DICT } from '/@/enums/dict';
  import { isFunction, isArray } from '/@/utils/is';
  import dayjs from 'dayjs';

  const userPoints = ref<any[]>([]);
  const useUser = useUserStore();
  const MapRef = ref<any>(null);
  const selectKeys = ref<string[]>([]);
  const loading = ref<boolean>(false);

  const lnglat = ref({
    lat: '',
    lng: '',
  });

  const personalRef = ref<any>(null);

  const list = ref([]);

  const MapHeight = ref<string>('calc(100vh - 112px)');

  const asyncExpandTreeRef = ref<any>('');

  const treeData = ref([]);

  const searchRef = ref<any>(null);

  let treeId = '';

  let time = dayjs().format('YYYY-MM-DD');

  let userId: string = useUser.getUserInfo.userId as string;

  const [register, { getFieldsValue }] = useForm({
    labelWidth: 120,
    schemas: searchInfo,
    submitFunc: async () => {
      const params = getFieldsValue();
      loading.value = true;
      time = params.time.split(' ')[0];
      getUserAddress(userId, time);
    },
    // actionColOptions: {
    //   span: 6,
    // },
    resetFunc: async () => {
      time = dayjs().format('YYYY-MM-DD');
      getUserAddress(userId, time);
    },
  });

  // 获取初始化地图中心定位点
  const getMapCenterPoints = async () => {
    const ret = await getDictTypeListApi({ type: DICT.MAP_CENTER_POINTERS });
    lnglat.value = {
      lng: ret[0].value,
      lat: ret[1].value,
    };
  };

  // 动态计算设置地图高度
  const setMapHeight = () => {
    let height = searchRef.value.offsetHeight;
    MapHeight.value = ` calc(100vh - 125px - ${height}px)`;
  };

  // 获取左侧列表
  const getUserList = async () => {
    const ret = await CommonAddressList({ sceneType: 1, addressType: 1 });
    treeData.value = ret.deptList;
    treeId = useUser.getUserInfo.deptId;
    selectKeys.value = [treeId];
    handleTreeSelect([treeId], (data) => {
      const index = getFindPersonal(data);
      nextTick(() => {
        personalRef.value && personalRef.value.setChecked(index);
      });
    });
    nextTick(() => {
      asyncExpandTreeRef.value && asyncExpandTreeRef.value.expandAll(true);
    });
  };
  // 查找人员
  const getFindPersonal = (data: any[], find = 'findIndex') => {
    return data[find]((i) => i.id === userId);
  };
  // 点击人员
  const changePersonal = async (item: any) => {
    if (!Object.keys(item).length) {
      loading.value = false;
      return;
    }
    userId = item.id;
    await getUserAddress(item.id, time);
  };

  onMounted(async () => {
    nextTick(() => {
      getUserList();
      getMapCenterPoints();
    });
  });
  const getUserAddress = async (id: string, time?: string) => {
    const ret = await getUserAddressList(id, time);
    const result = ret.map((i) => ({ ...i, lat: i.latitude, lng: i.longitude }));
    loading.value = false;
    userPoints.value = getLatLngDistance(result);
    console.log(
      '%c点位置距离==========',
      'color:#a8e;font-size:30px;font-weight:bold',
      userPoints.value,
    );
    const demo = getDistances('33.607856', '114.657966', '33.605702', '114.659178');
    console.log('demo-----------------', demo);

    const centerPoints = userPoints.value.length ? userPoints.value[0] : lnglat.value;

    MapRef.value && MapRef.value.redrawTrack(userPoints.value, centerPoints);
    setMapHeight();
  };

  const handleTreeSelect = async (ids: string[], callback?: Fn) => {
    if (!ids.length) return;

    loading.value = true;
    treeId = ids[0];
    const ret = await CommonAddressList({
      sceneType: 8,
      addressType: 1,
      orgInfo: {
        '1': ids[0],
      },
    });
    loading.value = false;
    list.value = ret.userList;

    if (!isFunction(callback)) {
      if (ret.userList?.[0]) {
        nextTick(() => {
          personalRef.value && personalRef.value.setChecked(0);
        });
      }
    }
    isFunction(callback) && callback(ret.userList);
  };

  // 经纬度换算
  const getLatLngDistance = (data: any[]): any[] => {
    console.log('%c源数据', 'color:#ea9;font-size:30px;font-weight:bold', data);

    if (!isArray(data)) return [];
    let initPoints: any[] = [];
    // let lastPoint: any[] = [];
    let delPoint: any[] = [];
    data.reverse();
    data.forEach((item) => {
      initPoints.push(item);
      if (delPoint.length) {
        initPoints = initPoints.filter((i) => !delPoint.includes(i.id));
      }
      // initPoints.push(...lastPoint);
      // lastPoint = [];
      delPoint = [];
      initPoints.forEach((i) => {
        const ret = getDistances(item.lat, item.lng, i.lat, i.lng);
        console.log('%c2点之间的距离', 'color:#ea9;font-size:30px;font-weight:bold', ret);
        if (ret.m < 100) {
          item.lastTime = i.lastTime || i.uploadTime;
          if (ret.m > 0) {
            delPoint.push(i.id);
          }
        }
      });
    });
    //Array.from(new Set(initPoints.map((i) => JSON.stringify(i)))).map((i) => JSON.parse(i));
    return initPoints.map((i) => ({
      ...i,
      uploadTime: i.lastTime !== i.uploadTime ? `${i.lastTime} ~ ${i.uploadTime}` : i.uploadTime,
    }));
  };

  // 根据经纬度计算距离，参数分别为第一点的纬度，经度；第二点的纬度，经度
  const getDistances = (lat1, lng1, lat2, lng2) => {
    let EARTH_RADIUS = 6378.137; // 地球半径
    let radLat1 = (lat1 * Math.PI) / 180.0; //lat1 * Math.PI / 180.0=>弧度计算
    let radLat2 = (lat2 * Math.PI) / 180.0;
    let a = radLat1 - radLat2;
    let b = (lng1 * Math.PI) / 180.0 - (lng2 * Math.PI) / 180.0;
    let s =
      2 *
      Math.asin(
        Math.sqrt(
          Math.pow(Math.sin(a / 2), 2) +
            Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2),
        ),
      );
    s = s * EARTH_RADIUS;
    s = Math.round(s * 10000) / 10000; // 输出为公里
    return { m: s * 1000, km: Number(s.toFixed(2)) };
  };
</script>

<style lang="less" scoped>
  :deep(.full-loading) {
    z-index: 9999 !important;
  }

  .map-cont {
    display: flex;
    // align-items: center;
    padding: 0 16px;

    :deep(.vben-tree-header) {
      border: 0;
    }

    :deep(.vben-basic-form) {
      .ant-form-item:not(.ant-form-item-with-help) {
        margin-bottom: 0;
      }
    }
  }

  .no-data {
    text-align: center;
    color: #ccc;
    display: flex;
    flex-direction: column;
    background: #fff;
    height: 100%;
    justify-content: center;

    .empty-img {
      display: flex;
      justify-content: center;
    }
  }
</style>
